package controllers

import java.io.File

import dao._
import javax.inject.Inject
import play.api.libs.json.Json
import play.api.mvc._
import utils.Utils

import scala.concurrent.ExecutionContext.Implicits.global
import tool._
import models.Tables._
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import shared.Shared
import utils.Utils.{Info, Sender}

import scala.concurrent.Future
import implicits.Implicits._

/**
 * Created by yz on 2018/8/20
 */
class AdminController @Inject()(cc: ControllerComponents, formTool: FormTool,
                                tool: Tool, missionDao: MissionDao, extraDataDao: ExtraDataDao,
                                trashDao: TrashDao, pdfInfoDao: PdfInfoDao,
                                implicit val userDao: UserDao,
                                implicit val rangeDao: RangeDao,
                                implicit val accountDao: AccountDao
                               ) extends AbstractController(cc) {

  def userManageBefore = Action { implicit request =>
    Ok(views.html.admin.userManage())
  }

  def getAllUser = Action.async { implicit request =>
    userDao.selectAll.map { x =>
      val array = Utils.getArrayByTs(x)
      Ok(Json.toJson(array))
    }
  }

  def userNameCheck = Action.async { implicit request =>
    val data = formTool.userNameForm.bindFromRequest.get
    userDao.selectByName(data.name).zip(accountDao.selectById1).map { case (optionUser, admin) =>
      optionUser match {
        case Some(y) => Ok(Json.obj("valid" -> false))
        case None =>
          val valid = if (data.name == admin.account) false else true
          Ok(Json.obj("valid" -> valid))
      }
    }
  }

  def changePasswordBefore = Action { implicit request =>
    Ok(views.html.admin.changePassword())
  }

  def changePassword = Action.async { implicit request =>
    val data = formTool.changePasswordForm.bindFromRequest().get
    accountDao.selectById1.flatMap { x =>
      if (data.password == x.password) {
        accountDao.updatePassword(data.newPassword).map { y =>
          Redirect(routes.AppController.loginBefore).flashing("info" -> "密码修改成功!", "class" -> Utils.successClass).
            removingFromSession(Shared.adminStr)
        }
      } else {
        Future.successful(Redirect(routes.AdminController.changePasswordBefore).flashing("info" -> "用户名或密码错误!", "class" -> Utils.errorClass))
      }
    }
  }

  def addUser = Action.async { implicit request =>
    val data = formTool.userForm.bindFromRequest().get
    val row = UserRow(0, data.name, data.password, new DateTime())
    userDao.insertAndReturning(row).flatMap { userId =>
      val pdfInfoRow = PdfInfoRow(userId, "深圳绘云医学检验实验室", "", "", "", "")
      val pdfInfoInsertF = pdfInfoDao.insert(pdfInfoRow)
      val defaultRange = Tool.defaultRange
      val rangeRow = RangeRow(userId = userId, astMin = defaultRange.astMin, astMax = defaultRange.astMax,
        altMin = defaultRange.altMin, altMax = defaultRange.altMax, pltMin = defaultRange.pltMin,
        pltMax = defaultRange.pltMax)
      val rangeInsertF = rangeDao.insert(rangeRow)
      pdfInfoInsertF.zip(rangeInsertF).map { x =>
        Ok(Json.toJson("success!"))
      }
    }
  }

  def updateUser = Action.async { implicit request =>
    val data = formTool.userForm.bindFromRequest().get
    userDao.update(data).map { x =>
      Ok("success!")
    }
  }

  def getUserById = Action.async { implicit request =>
    val data = formTool.idForm.bindFromRequest().get
    userDao.selectById(data.id).map { x =>
      Ok(Utils.getJsonByT(x))
    }
  }

  def deleteUserById = Action.async { implicit request =>
    val data = formTool.idForm.bindFromRequest().get
    userDao.deleteById(data.id).zip(pdfInfoDao.deleteById(data.id)).map { x =>
      Ok("success")
    }
  }

  def deleteUserData = Action.async { implicit request =>
    val data = formTool.idForm.bindFromRequest().get
    userDao.deleteById(data.id).zip(pdfInfoDao.deleteById(data.id)).zip(extraDataDao.deleteByUserId(data.id)).
      zip(missionDao.deleteByUserId(data.id)).zip(trashDao.deleteByUserId(data.id)).zip(rangeDao.deleteById(data.id)).map { x =>
      val userDir = new File(Utils.userDir, s"${data.id}")
      Utils.deleteDirectory(userDir)
      Ok("success")
    }
  }

  def logout = Action { implicit request =>
    Redirect(routes.AppController.loginBefore).flashing("info" -> "退出登录成功!", "class" -> Utils.successClass).
      removingFromSession(Shared.adminStr)
  }

  def userDataBefore = Action { implicit request =>
    Ok(views.html.admin.userData())
  }

  def getAllMission = Action.async { implicit request =>
    missionDao.selectAll.zip(extraDataDao.selectAll).
      zip(trashDao.selectAll).map { case ((missionRows, extraRows), trashs) =>
      val extraMap = extraRows.map(x => (x.id, x)).toMap
      val trashMap = trashs.map { x =>
        val isDelete = if (x.exist == 0) "否" else "是"
        (x.id, isDelete)
      }.toMap
      val t2s = missionRows.map(x => (x, extraMap.getOrElse(x.id, tool.getEmptyExtraDataRow(x.id, x.userId))))
      val array = Utils.getArrayByT2s(t2s).map { x =>
        x + ("isDelete" -> trashMap(x("id").toInt))
      }
      Ok(Json.toJson(array))
    }
  }

  def downloadDb = Action.async { implicit request =>
    missionDao.selectAll.zip(extraDataDao.selectAll).zip(userDao.selectAll).
      zip(trashDao.selectAll).map { case (((missionRows, extraRows), users), trashs) =>
      val extraMap = extraRows.map(x => (x.id, x)).toMap
      val userMap = users.map(x => (x.id, x.name)).toMap
      val trashMap = trashs.map { x =>
        val isDelete = if (x.exist) "否" else "是"
        (x.id, isDelete)
      }.toMap
      val headers = List("用户", "样品号", "姓名", "年龄", "AST", "ALT", "PLT", "风险得分", "结果", "时间", "是否删除",
        "送检单位", "地址", "性别", "送检科室", "申请医生", "门诊/住院号", "采样时间", "送检时间",
        "样本类型", "样本状态", "标题", "检验", "审核", "检验日期", "报告日期")
      val lines = headers :: missionRows.toList.map { x =>
        val userName = userMap.getOrElse(x.userId, "已删")
        val isDelete = trashMap(x.id)
        val extra = extraMap.getOrElse(x.id, tool.getEmptyExtraDataRow(x.id, x.userId))
        List(userName, extra.sampleId, extra.name, x.age, x.ast, x.alt, x.plt, x.score, x.result,
          Utils.dataTime2String(x.endTime), isDelete,
          extra.unit, extra.address, extra.sex, extra.office, extra.doctor, extra.number, extra.sampleTime, extra.submitTime,
          extra.sampleType, extra.sampleStatus, extra.title, extra.reporter, extra.checker, extra.submitTime,
          extra.reportDate)
      }.sortBy(_ (0))
      val tmpDir = tool.createTempDirectory("tmpDir")
      val file = new File(tmpDir, "db.txt")
      lines.toTxtFile(file)
      Ok.sendFile(file, onClose = () => {
        Utils.deleteDirectory(tmpDir)
      }).withHeaders(
        CONTENT_DISPOSITION -> s"attachment; filename=${
          file.getName
        }",
        CONTENT_TYPE -> "application/x-download"
      )

    }
  }

}
